{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e172ba32-dbe3-4e6f-a480-bc08307f3ace",
   "metadata": {},
   "source": [
    "## Mistral AI\n",
    "\n",
    "\n",
    "### Install Python Client\n",
    "\n",
    "https://docs.mistral.ai/platform/client/\n",
    "\n",
    "https://github.com/mistralai/client-python\n",
    "\n",
    "pip install mistralai\n",
    "\n",
    "### Mistral Azure\n",
    "\n",
    "https://github.com/Azure/azureml-examples/blob/main/sdk/python/foundation-models/mistral/langchain.ipynb\n",
    "\n",
    "pip install langchain langchain_mistralai\n",
    "\n",
    "### Mistral.ai console\n",
    "\n",
    "https://console.mistral.ai/usage/\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "945cd540-b243-407e-b5bc-347839ea75c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: mistralai\n",
      "Version: 0.1.6\n",
      "Summary: \n",
      "Home-page: \n",
      "Author: Bam4d\n",
      "Author-email: bam4d@mistral.ai\n",
      "License: \n",
      "Location: /opt/conda/lib/python3.11/site-packages\n",
      "Requires: httpx, orjson, pandas, pyarrow, pydantic\n",
      "Required-by: \n"
     ]
    }
   ],
   "source": [
    "!pip show mistralai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53b0140b-97b6-4339-8a1b-a6740ad4107d",
   "metadata": {},
   "source": [
    "## Create MistralClient "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a9cfc7ca-4d18-47d9-9803-cfedb09e3f09",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from mistralai.client import MistralClient\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "client = MistralClient(api_key=os.environ[\"MISTRAL_API_KEY\"])\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "942db54c-e86d-44a8-a2b9-7a9787d6ef6b",
   "metadata": {},
   "source": [
    "## Check Model List"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c7e6898c-d529-4b97-97e1-13f200babdc2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open-mistral-7b\n",
      "mistral-tiny-2312\n",
      "mistral-tiny\n",
      "open-mixtral-8x7b\n",
      "mistral-small-2312\n",
      "mistral-small\n",
      "mistral-small-2402\n",
      "mistral-small-latest\n",
      "mistral-medium-latest\n",
      "mistral-medium-2312\n",
      "mistral-medium\n",
      "mistral-large-latest\n",
      "mistral-large-2402\n"
     ]
    }
   ],
   "source": [
    "models = client.list_models()\n",
    "\n",
    "for i in range(0,len(models.data) -1):\n",
    "    print(models.data[i].id,flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d161b155-1832-4800-aa90-2001b59b2cfa",
   "metadata": {},
   "source": [
    "## Load instruction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "534ff961-7a09-4287-954d-458d8209e6af",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1/1 [00:00<00:00, 1267.16it/s]\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import DirectoryLoader, TextLoader\n",
    "\n",
    "loader = DirectoryLoader('structurizr/llm', glob=\"instruction.txt\", show_progress=True, use_multithreading=True, loader_cls=TextLoader)\n",
    "\n",
    "instruction = loader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "00f7037d-81fc-4710-920a-7387d07ae1b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You are an expert on structurizr which is a domain specific language (DSL) for software architecture modeling and documenation.\n",
      "You will be provided a keyword in structurizr DSL, you need to provide the keyword gramma precisely and consistently.\n",
      "You need to check the permited children of the keyword.\n",
      "You must strictly adhere to the keyword gramma to generate the output.\n",
      "You need to embed the permited children of the keyword in the gramma.\n",
      "You do not need to provide the permited children out of the gramma.\n",
      "You need to provide the gramma, you do not need to provide any explanations.\n",
      "You do not need to privde code examples or explanations. \n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(instruction[0].page_content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4184632a-eee3-4ce4-8f86-c9071e3f0dcf",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mistralai.models.chat_completion import ChatMessage\n",
    "\n",
    "messages = [\n",
    "    ChatMessage(role=\"system\", content=instruction[0].page_content),\n",
    "    ChatMessage(role=\"user\", content=\"workspace\")\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba471b66-0ba1-4887-a3e6-8b41efedec22",
   "metadata": {},
   "source": [
    "## Chat with \"open-mistral-7b\" using instruction only"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "73e47a0d-09e4-4c41-825c-777bb1cf5b9c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "workspace ::= \"workspace\" \"{\" ( (component ::= \"component\" id \"{\" ( (module ::= \"module\" id \"{\" permitedChildren* \"}\";)? (connection ::= \"connection\" source ref \"to\" target ref)*)? \"}\" )* \"}\"\n",
      "\n",
      "permitedChildren*: (component | module | container | system | node | code | containerConnection | systemConnection | componentConnection | moduleConnection | nodeConnection | codeConnection)\n",
      "CPU times: user 6.62 ms, sys: 2.09 ms, total: 8.7 ms\n",
      "Wall time: 2.11 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "chat_response = client.chat(\n",
    "    model=\"open-mistral-7b\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "print(chat_response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd6192a8-c067-4734-ae5e-e4be67ec2df9",
   "metadata": {},
   "source": [
    "## Chat with \"mistral-large-2402\" using instruction only"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "868f311f-73a1-46fb-9dc1-0d750b9a34f9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The gramma for the keyword \"workspace\" in structurizr DSL is as follows:\n",
      "\n",
      "```\n",
      "workspace {\n",
      "  name \"Workspace Name\"\n",
      "  [description \"Workspace Description\"]\n",
      "  [model [name \"Model Name\"]]\n",
      "  [views {\n",
      "    [systemLandscape name \"Landscape Name\" description \"Landscape Description\"]\n",
      "    [systemContext name \"Context Name\" description \"Context Description\"]\n",
      "    [container name \"Container Name\" description \"Container Description\"]\n",
      "    [component name \"Component Name\" description \"Component Description\"]\n",
      "  }]\n",
      "}\n",
      "```\n",
      "\n",
      "The permitted children of the keyword \"workspace\" are:\n",
      "- name\n",
      "- description (optional)\n",
      "- model (optional)\n",
      "- views (optional)\n",
      "    - systemLandscape\n",
      "    - systemContext\n",
      "    - container\n",
      "    - componentCPU times: user 430 ms, sys: 75.9 ms, total: 506 ms\n",
      "Wall time: 4.35 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "stream_response = client.chat_stream(\n",
    "    model=\"mistral-large-2402\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "for chunk in stream_response:\n",
    "    print(chunk.choices[0].delta.content, end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8077afa9-17c1-4ec2-93fb-bf64d4e27a84",
   "metadata": {},
   "source": [
    "## Load grammars and add to chat message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c5a50ab8-d4b9-479e-aa80-92d2d8542b61",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1/1 [00:00<00:00, 283.63it/s]\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import DirectoryLoader, TextLoader\n",
    "\n",
    "loader = DirectoryLoader('structurizr/llm', glob=\"grammar.txt\", show_progress=True, use_multithreading=True, loader_cls=TextLoader)\n",
    "\n",
    "grammars = loader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "57320b07-d600-48d0-aff4-41f2eb03d589",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The following describes the grammars:\n",
      "\n",
      "- Line breaks are important; long lines can be split with `\\` as the last character on the line.\n",
      "- Lines are processed in order.\n",
      "- Tokens must be separated by whitespace, but the quantity of whitespace/indentation isn't important.\n",
      "- Keywords are case-insensitive (e.g. you can use `softwareSystem` or `softwaresystem`).\n",
      "- Double quote characters (`\"...\"`) are required when a property/expression contains whitespace.\n",
      "- Opening curly brace symbols (`{`) must be on the same line (i.e. the last token of the statement, not on a line of their own).\n",
      "- Closing curly brace symbols (`}`) must be on a line of their own.\n",
      "- Opening/closing braces are only required when adding child content.\n",
      "- Use `\"\"` as a placeholder for an earlier optional property that you'd like to skip.\n",
      "- angle brackets (`<...>`) are used to show required properties, and square brackets (`[...]`) are used to show optional properties. \n",
      "- Most statements are of the form: `keyword <required properties> [optional properties]`.\n",
      "- Statement examples are defined in code blocks starting with \"```\" as the first line and ending with \"````\" as the last line, the \"...\" is used to represent the child content.\n",
      "- Keywords are defined in format `keyword`.\n",
      "- A property can only exist once within a statement.\n",
      "\n",
      "\n",
      "`workspace` is the top level language construct, and the wrapper for the [model](#model) and [views](#views). A workspace can optionally be given a name and description.\n",
      "\n",
      "```\n",
      "workspace [name] [description] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- name <name>\n",
      "- description <description>\n",
      "- [properties](#properties)\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [!identifiers](#identifier-scope)\n",
      "- [!impliedRelationships](#impliedrelationships)\n",
      "- [model](#model)\n",
      "- [views](#views)\n",
      "- [configuration](#configuration)\n",
      "\n",
      "\n",
      "The `model` keyword defines elements and relationships, each workspace must contain a `model` block.\n",
      "\n",
      "```\n",
      "model {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- [group](#group)\n",
      "- [person](#person)\n",
      "- [softwareSystem](#softwareSystem)\n",
      "- [deploymentEnvironment](#deploymentEnvironment)\n",
      "- [element](#element)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n",
      "\n",
      "The `person` keyword defines a person (e.g. a user, actor, role, or persona).\n",
      "\n",
      "```\n",
      "person <name> [description] [tags] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- [description](#description)\n",
      "- [tags](#tags)\n",
      "- [url](#url)\n",
      "- [properties](#properties)\n",
      "- [perspectives](#perspectives)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n",
      "\n",
      "The `softwareSystem` keyword defines a software system.\n",
      "\n",
      "```\n",
      "softwareSystem <name> [description] [tags] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [group](#group)\n",
      "- [container](#container)\n",
      "- [description](#description)\n",
      "- [tags](#tags)\n",
      "- [url](#url)\n",
      "- [properties](#properties)\n",
      "- [perspectives](#perspectives)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n",
      "The `container` keyword defines a container, within a software system.\n",
      "\n",
      "```\n",
      "container <name> [description] [technology] [tags] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [group](#group)\n",
      "- [component](#component)\n",
      "- [description](#description)\n",
      "- [technology](#technology)\n",
      "- [tags](#tags)\n",
      "- [url](#url)\n",
      "- [properties](#properties)\n",
      "- [perspectives](#perspectives)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n",
      "\n",
      "The `component` keyword defines a component, within a container.\n",
      "\n",
      "```\n",
      "component <name> [description] [technology] [tags] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [description](#description)\n",
      "- [technology](#technology)\n",
      "- [tags](#tags)\n",
      "- [url](#url)\n",
      "- [properties](#properties)\n",
      "- [perspectives](#perspectives)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n",
      "The `deploymentEnvironment` keyword provides a way to define a deployment environment (e.g. development, testing, staging, live, etc).\n",
      "\n",
      "```\n",
      "deploymentEnvironment <name> {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "\n",
      "- [group](#group)\n",
      "- [deploymentGroup](#deploymentGroup)\n",
      "- [deploymentNode](#deploymentNode)\n",
      "- [-> (relationship)](#relationship)\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(grammars[0].page_content,flush=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e31ee494-912d-4e3a-9deb-7d3d88408ca4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mistralai.models.chat_completion import ChatMessage\n",
    "\n",
    "messages = [\n",
    "    ChatMessage(role=\"system\", content=instruction[0].page_content + grammars[0].page_content),\n",
    "    ChatMessage(role=\"user\", content=\"workspace\")\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d9b7df9-ac35-4107-a246-365c0428ebdc",
   "metadata": {},
   "source": [
    "## Chat with \"open-mistral-7b\" using instruction and grammars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "37dba09c-cb6f-4ab5-b441-9ad6198629ff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "```\n",
      "workspace [name] [description] {\n",
      "    model {\n",
      "        // definitions for software systems, containers, components, etc.\n",
      "    }\n",
      "    views [name] {\n",
      "        // definitions for views\n",
      "    }\n",
      "    [!docs]\n",
      "    [!adrs]\n",
      "    [!identifiers]\n",
      "    [!impliedRelationships]\n",
      "}\n",
      "```\n",
      "CPU times: user 7.89 ms, sys: 4.18 ms, total: 12.1 ms\n",
      "Wall time: 1.13 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "chat_response = client.chat(\n",
    "    model=\"open-mistral-7b\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "print(chat_response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "539f2b49-a73a-4d56-848e-e4ea832217d5",
   "metadata": {},
   "source": [
    "## Chat with \"mistral-large-2402\" using instruction and grammars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "225c0d3a-885b-4659-a6d4-d5d93a5480fe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The grammar for the `workspace` keyword in structurizr DSL is as follows:\n",
      "\n",
      "```\n",
      "workspace [name] [description] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- name <name>\n",
      "- description <description>\n",
      "- [properties](#properties)\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [!identifiers](#identifier-scope)\n",
      "- [!impliedRelationships](#impliedrelationships)\n",
      "- [model](#model)\n",
      "- [views](#views)\n",
      "- [configuration](#configuration)"
     ]
    }
   ],
   "source": [
    "stream_response = client.chat_stream(\n",
    "    model=\"mistral-large-2402\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "for chunk in stream_response:\n",
    "    print(chunk.choices[0].delta.content, end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d9b595a-520f-493e-ba82-66d71f00e66c",
   "metadata": {},
   "source": [
    "## Load the language reference markdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "67703e74-2b73-482c-887e-e499d627c475",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1/1 [00:00<00:00, 485.62it/s]\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import DirectoryLoader, TextLoader\n",
    "\n",
    "loader = DirectoryLoader('structurizr/dsl/docs', glob=\"language-reference.md\", show_progress=True, use_multithreading=True, loader_cls=TextLoader)\n",
    "\n",
    "language = loader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2fa5829e-4c51-41c2-b3e0-1faee251b359",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mistralai.models.chat_completion import ChatMessage\n",
    "\n",
    "messages = [\n",
    "    ChatMessage(role=\"system\", content=instruction[0].page_content + language[0].page_content),\n",
    "    ChatMessage(role=\"user\", content=\"workspace\")\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21645fd6-88af-4e32-8d5a-b29fe58264b3",
   "metadata": {},
   "source": [
    "## Chat with \"open-mistral-7b\" using instruction and language-reference"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "683a4a34-60bb-46ca-a460-119b0aae79c2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "```vbnet\n",
      "workspace {\n",
      "  !docs \"documents\"\n",
      "  !adrs \"adr\"\n",
      "\n",
      "  model {\n",
      "    person \"User\"\n",
      "    softwareSystem \"Software System\" {\n",
      "      webapp = container \"Web Application\"\n",
      "      database = container \"Database\"\n",
      "      \n",
      "      user -> webapp \"Uses\"\n",
      "      webapp -> database \"Reads from and writes to\"\n",
      "    }\n",
      "    \n",
      "    views {\n",
      "      theme default\n",
      "    }\n",
      "  }\n",
      "\n",
      "  !script kotlin {\n",
      "    workspace.views.createDefaultViews()\n",
      "    workspace.views.views.forEach { it.disableAutomaticLayout() }\n",
      "  }\n",
      "}\n",
      "```\n",
      "CPU times: user 22.4 ms, sys: 1.83 ms, total: 24.2 ms\n",
      "Wall time: 4.56 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "chat_response = client.chat(\n",
    "    model=\"open-mistral-7b\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "print(chat_response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "69e42bca-742b-4f7c-85d2-1702b248a908",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "```structurizr\n",
      "workspace {\n",
      "\n",
      "    model {\n",
      "        softwareSystem \"Software System 1\" {\n",
      "            container \"Container 1\" {\n",
      "                component \"Component 1\"\n",
      "            }\n",
      "        }\n",
      "\n",
      "        softwareSystem \"Software System 2\" {\n",
      "            container \"Container 2\" {\n",
      "                component \"Component 2\"\n",
      "            }\n",
      "        }\n",
      "    }\n",
      "\n",
      "    views {\n",
      "        systemLandscape {\n",
      "            elements ->*\n",
      "            relationships ->*\n",
      "            title \"System Landscape Diagram\"\n",
      "        }\n",
      "        systemContext {\n",
      "            softwareSystem1 ->*\n",
      "            title \"System Context Diagram for Software System 1\"\n",
      "        }\n",
      "        container {\n",
      "            softwareSystem1.container1 ->*\n",
      "            title \"Container Diagram for Container 1 in Software System 1\"\n",
      "        }\n",
      "        component {\n",
      "            softwareSystem1.container1.component1 ->*\n",
      "            title \"Component Diagram for Component 1 in Container 1 in Software System 1\"\n",
      "        }\n",
      "    }\n",
      "\n",
      "    !impliedRelationships true\n",
      "    !identifiers hierarchical\n",
      "    !docs docs\n",
      "    !adrs adrs\n",
      "\n",
      "}\n",
      "```CPU times: user 569 ms, sys: 115 ms, total: 684 ms\n",
      "Wall time: 6.61 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "stream_response = client.chat_stream(\n",
    "    model=\"open-mistral-7b\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "for chunk in stream_response:\n",
    "    print(chunk.choices[0].delta.content, end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddb6b65a-ff85-4098-b61b-da530ebcddc5",
   "metadata": {},
   "source": [
    "## Chat with \"mistral-large-2402\" using instruction and language-reference"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f373f5ba-ade2-466d-9db0-fd56344935a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The `workspace` keyword is used to define the top-level language construct in the Structurizr DSL. It is the wrapper for the model and views. A workspace can optionally be given a name and description. The syntax is as follows:\n",
      "\n",
      "```\n",
      "workspace [name] [description] {\n",
      "    ...\n",
      "}\n",
      "```\n",
      "\n",
      "A workspace can also extend another workspace, to add more elements, relationships, views, etc to it. The base workspace can either be referenced using a local DSL/JSON file, or a remote (via a HTTPS URL) DSL/JSON file. When extending a DSL-based workspace, all of the identifiers defined in that workspace are available to use in the extended workspace.\n",
      "\n",
      "Permitted children:\n",
      "\n",
      "- name <name>\n",
      "- description <description>\n",
      "- [properties](#properties)\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [!identifiers](#identifier-scope)\n",
      "- [!impliedRelationships](#impliedrelationships)\n",
      "- [model](#model)\n",
      "- [views](#views)\n",
      "- [configuration](#configuration)CPU times: user 863 ms, sys: 180 ms, total: 1.04 s\n",
      "Wall time: 10.8 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "stream_response = client.chat_stream(\n",
    "    model=\"mistral-large-2402\",\n",
    "    messages=messages,\n",
    ")\n",
    "\n",
    "for chunk in stream_response:\n",
    "    print(chunk.choices[0].delta.content, end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43a42f3e-609d-4dc0-9dfd-29f09027cec5",
   "metadata": {},
   "source": [
    "## Embedding "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "6e7b7f02-56c4-4a7d-afbb-db1b56cbbb58",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 32.6 ms, sys: 6.12 ms, total: 38.7 ms\n",
      "Wall time: 1.01 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "embeddings_batch_response = client.embeddings(\n",
    "      model=\"mistral-embed\",\n",
    "      input=[\"Embed this sentence.\", \"As well as this one.\"],\n",
    "  )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "2ca59e33-46b0-4de2-a88d-f66144be90d2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "prompt_tokens=15 total_tokens=15 completion_tokens=0\n"
     ]
    }
   ],
   "source": [
    "print(embeddings_batch_response.usage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "443151cb-38fc-4ac5-976f-72a17158133a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1024\n"
     ]
    }
   ],
   "source": [
    "print(len(embeddings_batch_response.data[0].embedding))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "86f2fb66-a429-4eb5-a1fd-f18d0ab98198",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.0165863037109375\n"
     ]
    }
   ],
   "source": [
    "print(embeddings_batch_response.data[0].embedding[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33d26985-2238-43fe-9bd7-646f40c8b67b",
   "metadata": {},
   "source": [
    "## Check token usage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "317fa3e7-47b4-45dd-b872-057a801da3e5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ChatCompletionResponse(id='c36ff55142cc42148cca209b486e255b', object='chat.completion', created=1710652630, model='open-mistral-7b', choices=[ChatCompletionResponseChoice(index=0, message=ChatMessage(role='assistant', content='```vbnet\\nworkspace {\\n  !docs \"documents\"\\n  !adrs \"adr\"\\n\\n  model {\\n    person \"User\"\\n    softwareSystem \"Software System\" {\\n      webapp = container \"Web Application\"\\n      database = container \"Database\"\\n      \\n      user -> webapp \"Uses\"\\n      webapp -> database \"Reads from and writes to\"\\n    }\\n    \\n    views {\\n      theme default\\n    }\\n  }\\n\\n  !script kotlin {\\n    workspace.views.createDefaultViews()\\n    workspace.views.views.forEach { it.disableAutomaticLayout() }\\n  }\\n}\\n```', name=None, tool_calls=None), finish_reason=<FinishReason.stop: 'stop'>)], usage=UsageInfo(prompt_tokens=15169, total_tokens=15321, completion_tokens=152))"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat_response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "498f45be-9ae5-4218-88e8-4f779db1097c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "UsageInfo(prompt_tokens=15169, total_tokens=15321, completion_tokens=152)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chat_response.usage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "9245470e-de06-405e-aa4c-0de32496b83d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<generator object MistralClient.chat_stream at 0xffff6dae8040>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stream_response"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "712e2883-d8de-402b-a871-8693fa446d7c",
   "metadata": {},
   "source": [
    "## Read language reference markdown document"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "c00c72a6-dbac-4397-a9d5-03c47e9b1f0c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1/1 [00:00<00:00, 439.70it/s]\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import DirectoryLoader, TextLoader\n",
    "\n",
    "loader = DirectoryLoader('structurizr/dsl/docs', glob=\"language-reference.md\", show_progress=True, use_multithreading=True, loader_cls=TextLoader)\n",
    "\n",
    "markdown_documents = loader.load()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0c85072-8972-419b-b1b1-cb9abe9ec5f6",
   "metadata": {},
   "source": [
    "### Split markdown document by using MarkdownHeaderTextSplitter\n",
    "\n",
    "https://python.langchain.com/docs/modules/data_connection/document_transformers/markdown_header_metadata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "bdd9ec5d-48a9-44c8-b40a-37e2c876507c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.text_splitter import MarkdownHeaderTextSplitter\n",
    "\n",
    "headers_to_split_on = [\n",
    "    (\"#\", \"Header 1\"),\n",
    "    (\"##\", \"Header 2\"),\n",
    "    (\"###\", \"Header 3\"),\n",
    "]\n",
    "\n",
    "markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)\n",
    "\n",
    "md_header_splits = markdown_splitter.split_text(markdown_documents[0].page_content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "70158bb5-39ab-4c6f-b74b-24f165fdee7b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Header 1': 'Language reference', 'Header 2': 'Grammar', 'Header 3': 'workspace'}\n"
     ]
    }
   ],
   "source": [
    "print(md_header_splits[15].metadata)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "f91d20a5-59dc-480e-8207-32aaa1552f08",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "`workspace` is the top level language construct, and the wrapper for the [model](#model) and [views](#views). A workspace can optionally be given a name and description.  \n",
      "```\n",
      "workspace [name] [description] {\n",
      "...\n",
      "}\n",
      "```  \n",
      "A workspace can also extend another workspace, to add more elements, relationships, views, etc to it.  \n",
      "```\n",
      "workspace extends <file|url> {\n",
      "...\n",
      "}\n",
      "```  \n",
      "The base workspace can either be referenced using a local DSL/JSON file, or a remote (via a HTTPS URL) DSL/JSON file.\n",
      "When extending a DSL-based workspace, all of the identifiers defined in that workspace are available to use in the extended workspace.  \n",
      "Permitted children:  \n",
      "- name <name>\n",
      "- description <description>\n",
      "- [properties](#properties)\n",
      "- [!docs](#documentation)\n",
      "- [!adrs](#architecture-decision-records-adrs)\n",
      "- [!identifiers](#identifier-scope)\n",
      "- [!impliedRelationships](#impliedrelationships)\n",
      "- [model](#model)\n",
      "- [views](#views)\n",
      "- [configuration](#configuration)\n"
     ]
    }
   ],
   "source": [
    "print(md_header_splits[15].page_content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c40e67c6-8537-473c-aa82-fe19097518f2",
   "metadata": {},
   "source": [
    "### Embed markdown sections"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2c43a155-abf9-42a0-94a8-b6abc32f6b70",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "## Skip the first 2 sections which are the \"## Table of contents\"\n",
    "\n",
    "for section in md_header_splits[2:]:\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
